#include "pch.h"
#include "EnemyShip.h"
#include "Explosion.h"
#include "GameTime.h"
#include "Random.h"
#include "SoundManager.h"

namespace
{  
   dxroids::Ship::Attributes get_attrs()
   {
      dxroids::Ship::Attributes attrs;
      attrs.MaximumNumberOfShots = 1;
      attrs.MaximumShotDistance = 600.0f;
      attrs.MaximumVelocity = 14.0f;
      attrs.ThrustMagnitude = 1.0f;      
      attrs.ShotVelocity = 10.0f;
      return attrs;
   }   
}

dxroids::EnemyShip::EnemyShip(std::shared_ptr<SoundManager> const & _sound_manager, Size _size, Vector const & _pos)
   : Ship(_pos, 1.0f, (_size == Size::Large ? 40.0f : 20.0f), get_attrs())
   , size_(_size)   
   , effect_(_size == Size::Large ? SoundEffect::SaucerBig : SoundEffect::SaucerSmall)
   , sound_manager_(_sound_manager)
{   

   if (_sound_manager)
   {
      _sound_manager->Play(effect_, true);
   }

   RegisterTimedCallback(1.0f, [&](GameTime const & _timer)
   {
      Random rand;
      if (rand.Next(1, 100) % 2 == 0)
      {
         FireShot(_sound_manager);
      }
      return true;
   });
}

dxroids::EnemyShip::~EnemyShip()
{
   if (sound_manager_)
   {
      sound_manager_->Stop(effect_);
   }
}

DXROIDS_COM_PTR<ID2D1Geometry> dxroids::EnemyShip::CreateShipGeometry(
   DXROIDS_COM_PTR<ID2D1Factory> const & _factory, float _scale)
{   
   float scale = 1.0f;
   if (size_ == Size::Small)
   {
      scale = 0.5f;
   }

   DXROIDS_COM_PTR<ID2D1PathGeometry> path;
   DXROIDS_COM_PTR<ID2D1GeometrySink> sink;

   ThrowIfFailed(_factory->CreatePathGeometry(&path));
   ThrowIfFailed(path->Open(&sink));

   sink->BeginFigure(make_point(-5.0f, -15.0f, scale), D2D1_FIGURE_BEGIN_FILLED);
   sink->AddLine(make_point(5.0f, -15.0f, scale));
   sink->AddLine(make_point(10.0f, -5.0f, scale));
   sink->AddLine(make_point(-10.0f, -5.0f, scale));
   sink->EndFigure(D2D1_FIGURE_END_CLOSED);

   sink->BeginFigure(make_point(-10.0f, -5.0f, scale), D2D1_FIGURE_BEGIN_FILLED);
   sink->AddLine(make_point(-25.0f, 5.0f, scale));
   sink->AddLine(make_point(25.0f, 5.0f, scale));
   sink->AddLine(make_point(10.0f, -5.0f, scale));
   sink->EndFigure(D2D1_FIGURE_END_OPEN);
   
   sink->BeginFigure(make_point(-25.0f, 5.0f, scale), D2D1_FIGURE_BEGIN_FILLED);
   sink->AddLine(make_point(-10.0f, 15.0f, scale));
   sink->AddLine(make_point(10.0f, 15.0f, scale));
   sink->AddLine(make_point(25.0f, 5.0f, scale));
   sink->EndFigure(D2D1_FIGURE_END_OPEN);

   ThrowIfFailed(sink->Close());
   DXROIDS_COM_PTR<ID2D1Geometry> geometry(path);

   return geometry;
}

DXROIDS_COM_PTR<ID2D1Geometry> dxroids::EnemyShip::CreateThrustGeometry(
   DXROIDS_COM_PTR<ID2D1Factory> const & _factory, float _scale)
{
   return nullptr;
}

std::unique_ptr<dxroids::GameObject> dxroids::EnemyShip::Destroy(std::shared_ptr<SoundManager> const & _sound_manager)
{
   if (size_ == Size::Large)
   {
      if (_sound_manager)
      {
         _sound_manager->Play(SoundEffect::BangLarge);
      }
   }
   else
   {
      if (_sound_manager)
      {
         _sound_manager->Play(SoundEffect::BangSmall);
      }
   }
   _sound_manager->Stop(effect_);
   SetIsActive(false);   

   return Explosion::NewDefault(GetPosition());
}

float dxroids::EnemyShip::GetNextShotDirection() const
{   
   Vector const & pos = GetPosition();
   float const dy = target_.GetY() - pos.GetY();
   float const dx = target_.GetX() - pos.GetX();
   float const radians = atan2(dy, dx) + DXROIDS_MATH_PI_OVER_2;
   float const degrees = radians * 180 / DXROIDS_MATH_PI;   
   return degrees;
}



